package com.cv.platform.service.collection;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.cv.framework.common.pojo.PageResult;
import com.cv.framework.common.utils.object.BeanUtils;
import com.cv.framework.mybatis.core.query.QueryWrapperX;
import com.cv.framework.security.core.utils.SecurityFrameworkUtil;
import com.cv.infra.api.file.FileApi;
import com.cv.platform.controller.platform.collection.vo.collection.*;
import com.cv.platform.controller.platform.collection.vo.ref.CvVideoCollectionRefSaveReqVO;
import com.cv.platform.controller.platform.video.vo.CvVideoItemRespVO;
import com.cv.platform.dal.dataobject.collection.CvVideoCollectionDO;
import com.cv.platform.dal.mapper.collection.CvVideoCollectionMapper;
import com.cv.platform.enums.YesOrNoEnum;
import com.cv.platform.service.video.CvVideoService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 视频合集业务层接口实现类
 *
 * @author Charles_XDXD
 */
@Service
public class CvVideoCollectionServiceImpl implements CvVideoCollectionService {

    @Resource
    private CvVideoCollectionMapper cvVideoCollectionMapper;

    @Resource
    private CvVideoCollectionRefService cvVideoCollectionRefService;

    @Resource
    @Lazy
    private CvVideoService cvVideoService;

    @DubboReference
    private FileApi fileApi;

    @Override
    public Long createCollection(CvVideoCollectionSaveReqVO reqVO) {
        CvVideoCollectionDO recordDO = BeanUtils.toBean(reqVO, CvVideoCollectionDO.class);
        recordDO.setUserId(SecurityFrameworkUtil.getLoginUserId());
        cvVideoCollectionMapper.insert(recordDO);
        Long recordId = recordDO.getId();

        if (CollUtil.isNotEmpty(reqVO.getVideoIdList())) {
            for (int i = 0; i < reqVO.getVideoIdList().size(); i++) {
                CvVideoCollectionRefSaveReqVO saveReqVO = new CvVideoCollectionRefSaveReqVO()
                        .setCollectionId(recordId)
                        .setVideoId(reqVO.getVideoIdList().get(i))
                        .setSorted(i + 1);
                cvVideoCollectionRefService.saveCvVideoCollectionRef(saveReqVO);
            }
        }

        return recordId;
    }

    @Override
    public Long updateCollection(CvVideoCollectionSaveReqVO reqVO) {
        CvVideoCollectionDO recordDO = BeanUtils.toBean(reqVO, CvVideoCollectionDO.class);
        cvVideoCollectionMapper.updateById(recordDO);

        // 先清空再保存，这样效率会比逐个比对删除更快
        cvVideoCollectionRefService.deleteCvVideoCollectionRef(recordDO.getId());
        if (CollUtil.isNotEmpty(reqVO.getVideoIdList())) {
            for (int i = 0; i < reqVO.getVideoIdList().size(); i++) {
                Long videoId = reqVO.getVideoIdList().get(i);
                CvVideoCollectionRefSaveReqVO saveReqVO = new CvVideoCollectionRefSaveReqVO()
                        .setCollectionId(recordDO.getId())
                        .setVideoId(videoId)
                        .setSorted(i + 1);
                cvVideoCollectionRefService.saveCvVideoCollectionRef(saveReqVO);
            }
        }
        return recordDO.getId();
    }

    @Override
    public void deleteCollection(Long id) {
        cvVideoCollectionMapper.deleteById(id);
        cvVideoCollectionRefService.deleteCvVideoCollectionRef(id);
    }

    @Override
    public PageResult<CvVideoCollectionRespVO> getCollectionPage(CvVideoCollectionPageReqVO reqVO) {
        PageResult<CvVideoCollectionRespVO> pageResult;
        if (!reqVO.getUserId().equals(SecurityFrameworkUtil.getLoginUserId())) {
            pageResult = cvVideoCollectionMapper.selectPage(reqVO, YesOrNoEnum.YES.getCode());
        } else {
            pageResult = cvVideoCollectionMapper.selectPage(reqVO, YesOrNoEnum.NO.getCode());
        }

        pageResult.getList().forEach(item -> {
            item.setVideoIdList(cvVideoCollectionRefService.getVideoIdListByCollectionId(item.getId()));
            item.setThumbnailUrl(cvVideoCollectionRefService.getFirstVideoThumbnailUrlByCollectionId(item.getId()));
        });

        return pageResult;
    }

    @Override
    public CvVideoCollectionDetailRespVO getCollection(CvVideoCollectionDetailPageReqVO reqVO) {
        if (ObjUtil.isEmpty(reqVO.getId())) {
            return null;
        }
        CvVideoCollectionDO cvVideoCollectionDO = cvVideoCollectionMapper.selectById(reqVO.getId());
        CvVideoCollectionDetailRespVO respVO = BeanUtils.toBean(cvVideoCollectionDO, CvVideoCollectionDetailRespVO.class);

        List<Long> videoIds = cvVideoCollectionRefService.getVideoIdListByCollectionId(reqVO.getId());
        if (ObjUtil.isEmpty(videoIds)) {
            respVO.setVideoList(PageResult.empty());
            return respVO;
        }

        PageResult<CvVideoItemRespVO> pageResult = cvVideoService.getCollectionVideoPage(reqVO, videoIds);
        if (pageResult.equals(PageResult.empty())) {
            respVO.setVideoList(pageResult);
            return respVO;
        }

        List<CvVideoItemRespVO> videoList = pageResult.getList();

        videoList.forEach(item -> {
            item.setThumbnailUrl(fileApi.getUrl(item.getThumbnail()));
        });
        respVO.setVideoList(pageResult);
        return respVO;
    }

    @Override
    public List<Long> getVideoIdList() {
        Long userId = SecurityFrameworkUtil.getLoginUserId();
        if (ObjUtil.isEmpty(userId)) {
            return Collections.emptyList();
        }

        QueryWrapperX<CvVideoCollectionDO> wrapperX = new QueryWrapperX<CvVideoCollectionDO>()
                .eq("user_id", userId);
        List<CvVideoCollectionDO> cvVideoCollectionDOList = cvVideoCollectionMapper.selectList(wrapperX);

        if (CollUtil.isEmpty(cvVideoCollectionDOList)) {
            return Collections.emptyList();
        }

        List<Long> collectionIdList = cvVideoCollectionDOList.stream().map(CvVideoCollectionDO::getId).toList();
        List<Long> resp = new ArrayList<>();

        collectionIdList.forEach(id -> {
            resp.addAll(cvVideoCollectionRefService.getVideoIdListByCollectionId(id));
        });

        return resp;
    }

}
